//断线重连, 心跳机制 websocket
class Ws {
  constructor(url, options = {}) {
    this.url = url;
    this.options = options;
    this.socket = null;
    this.reconnectAttempts = 0; // 重连尝试次数
    this.reconnectInterval = options.reconnectInterval || 5000; // 重连间隔，默认5秒
    this.heartbeatInterval = options.heartbeatInterval || 11000; // 心跳间隔，默认30秒
    this.heartbeatTimeout = options.heartbeatTimeout || 10000; // 心跳超时时间，默认10秒
    this.reconnectTimeOutId = null; // 重连定时器id
    this.heartbeatTimeoutId = null; //心跳信息接收超时定时器id
    this.heartbeatTimerId = null; //心跳定时器id
    this.forbidReconnect = false; //禁止重连
  }
  messageType = {
    ping: "ping", //type为ping的时候 是当做心跳机制的
    checkAiJob: "checkAiJob", //查询是否有正在进行中的任务
    taskId: "taskId", //后台主动派发给我正在进行中的任务的进度情况
    message: "message",
    close: "close", //手动关闭连接
  };
  connect() {
    return new Promise((resolve, reject) => {
      this.forbidReconnect = false;
      try {
        this.socket = new WebSocket(this.url);
        this.bindEvent(resolve, reject);
      } catch (err) {
        reject(err);
      }
    });
  }
  bindEvent(resolve) {
    this.socket.addEventListener("open", this.handleOpen.bind(this, resolve));
    this.socket.addEventListener("message", this.handleMessage.bind(this));
    this.socket.addEventListener("error", this.handleError.bind(this));
    this.socket.addEventListener("close", this.handleClose.bind(this));
  }
  handleOpen(resolve) {
    if (this.socket.readyState === WebSocket.OPEN) {
      this.reconnectAttempts = 0;
      this.startHeartbeat();
      resolve(this.socket);
    }
  }
  handleMessage(event) {
    let obj = JSON.parse(event.data);
    console.log(obj, 1111);
    console.log(self, "111111");
    self.ports.forEach((item) => {
      item.postMessage({
        type: "ws",
        data: obj,
      });
    });
    if (obj.type == "close") {
      this.forbidReconnect = true;
      this.close();
    }
    //有信息返回的话就重置心跳机制
    this.resetHeartbeatTimeout();
  }
  handleError(error) {
    this.closeAllTimers();
    console.log("WebSocket error:", error);
    // this.reconnect();
  }
  handleClose() {
    //关闭的话重连
    this.closeAllTimers();
    //禁止重连
    if (this.forbidReconnect) return;
    this.reconnect();
    console.log("WebSocket disconnected");
  }
  // 关闭所有定时器
  closeAllTimers() {
    clearInterval(this.reconnectTimeOutId);
    clearInterval(this.heartbeatTimeoutId);
    clearInterval(this.heartbeatTimerId);
  }
  //开启心跳机制 , 定时发送ping
  startHeartbeat() {
    this.heartbeatTimerId = setInterval(() => {
      this.sendHeartbeat();
    }, this.heartbeatInterval);
  }
  //发送心跳信息
  sendHeartbeat() {
    //目前websocket是连接连接状态的话 , 发送心跳
    if (this.socket.readyState === WebSocket.OPEN) {
      this.send({ type: "ping", data: "pong" });
      //开始超时处理
      this.startHeartbeatTimeout();
    }
  }
  //超时处理
  startHeartbeatTimeout() {
    //如果返回超时了就关闭连接 , 然后再close中重新连接
    this.heartbeatTimeoutId = setTimeout(() => {
      console.error("Heartbeat timeout, disconnecting and reconnecting...");
      this.socket.close();
    }, this.heartbeatTimeout);
  }
  //重置心跳
  resetHeartbeatTimeout() {
    //超时事件关闭
    clearTimeout(this.heartbeatTimeoutId);
    clearTimeout(this.heartbeatTimerId);
    this.startHeartbeat();
  }
  //关闭心跳机制
  stopHeartbeat() {
    clearInterval(this.heartbeatTimerId);
    clearTimeout(this.heartbeatTimeoutId);
  }
  //发送信息
  send({ type, data = "" }) {
    return new Promise((resolve, reject) => {
      let obj = {
        type: this.messageType[type],
      };
      if (data) {
        obj.data = data;
      }
      if (this.socket.readyState === WebSocket.OPEN) {
        this.socket.send(JSON.stringify(obj));
        resolve();
      } else {
        reject("WebSocket is not connected");
      }
    });
  }
  //重连
  reconnect() {
    // if (this.reconnectAttempts < 3) {
    // 限制重连尝试次数，例如3次
    this.reconnectAttempts++;
    console.log(`Reconnecting attempt #${this.reconnectAttempts}`);
    this.heartbeatTimeoutId = setTimeout(() => {
      this.connect()
        .then(() => {
          console.log("Reconnected successfully");
        })
        .catch((err) => {
          console.error("Reconnect failed:", err);
          this.reconnect(); // 递归重连
        });
    }, this.reconnectInterval);
    // } else {
    //   console.log("Max reconnect attempts reached");
    // }
  }

  close() {
    if (this.socket) {
      this.socket.close();
      this.stopHeartbeat();
    }
  }
  isConnected() {
    return this.socket.readyState === WebSocket.OPEN;
  }
}

export default Ws;
